# -*- coding: utf-8 -*-
'''
    :file: auth.py
    :author: -Farmer
    :url: https://blog.farmer233.top
    :date: 2021/02/11 21:44:28
'''
from flask import Blueprint, g
from flask.globals import current_app, request
from flask_restful import Api, Resource
# from sqlalchemy.sql.expression import except_, true
# from sqlalchemy.sql.functions import user
#
from app.models import User
from app.extensions import auth, db
from app.utils import TokenTimeout, make_res
from app.forms.auth import RegisterForm, RestPasswordForm
# from app.operation.users import RegUser
auth_bp = Blueprint("auth", __name__)
api = Api(auth_bp)


class Reg(Resource):
    ''' 
        注册用户接口
        支持post、get两种方法
    '''

    def get(self):
        username = request.args.get("username")
        address = request.args.get("address")
        password = request.args.get('password')
        email = request.args.get('email')

        if username is None or password is None or email is None:
            return make_res(code=-1, message="必要参数缺失")
        else:
            try:
                self.reg(username, password, email, address)
                return make_res(data={
                    "username": username
                })
            except ValueError as e:
                current_app.logger.info(e)
                return make_res(code=-1, message=str(e))
            except Exception as e:
                current_app.logger.warning(e)

    def post(self):
        req_data = request.get_json()
        username = req_data.get("username")
        address = req_data.get("address")
        password = req_data.get('password')
        email = req_data.get('email')

        if username is None or password is None or email is None:
            return make_res(code=-1, message="必要参数缺失")
        else:
            try:
                self.reg(username, password, email, address)
                return make_res(data={
                    "username": username
                })
            except ValueError as e:
                current_app.logger.info(e)
                return make_res(code=-1, message=str(e))
            except Exception as e:
                current_app.logger.warning(e)

    def reg(self, username, password, email, address):
        reg_user = RegisterForm(address=address)
        reg_user.set_email(email=email)
        reg_user.set_username(username=username)
        reg_user.set_password(password=password)
        db.session.add(reg_user)
        db.session.commit()


class Login(Resource):
    ''' 用户登录接口 '''
    def post(self):
        try:
            req_data = request.get_json()
            username = req_data.get("username")
            password = req_data.get("password")
            expiration = req_data.get('expiration')
            token = self.login(username, password, expiration)
            return make_res(data={
                "username": username,
                "token": token
            })
        except ValueError as e:
            current_app.logger.info(e)
            return make_res(code=-1, message=str(e))
        except Exception as e:
            current_app.logger.warning(e)
            return make_res(code=-1, message=str(e))
        except Exception as e:
            current_app.logger.warning(e)

    def login(self, username, password, expiration=600):
        if username is None or password is None:
            raise ValueError("用户名或密码未输入")

        user = User.query.filter(User.username == username).first()
        if user is None:
            raise ValueError("用户未注册")
        if not user.validate_password(password):
            raise ValueError("密码不正确")
        else:
            token = user.generate_auth_token(expiration)
            return token

# 检查重置验证码是否正确接口
class CheckResetCode(Resource):
    def post(self):
        try:
            req_data = request.get_json()
            username = req_data.get('username', None)
            reset_code = str(req_data.get('code', None))
            reset_token = req_data.get('token')
            print(username, reset_code, reset_token)
            if username is None or reset_code is None or reset_token is None:
                return make_res(code=-1, message="缺少必要参数")
            
            rest = RestPasswordForm(username = username)
            # check_code 检查成功返回用户对象
            print('check')
            reset_user: User = rest.check_code(reset_token, reset_code)
            if reset_user:
                # 返回登录权限
                reset_token = reset_user.generate_auth_token(300)
                return make_res(message="请在5分钟内修改密码", data={
                    'resetToken': reset_token
                })
        except AttributeError as e:
            return make_res(code=-1, message="请求方式错误")
        except ValueError as e:
            current_app.logger.info(e)
            return make_res(code=-1, message=str(e))
        except Exception as e:
            current_app.logger.warning(e)
            return make_res(code=-1, message=str(e))

# 发送验证码接口
class SendForgetCodeView(Resource):
    # # decorators = [auth.login_required]

    def post(self):
        try:
            req_data = request.get_json()
        except AttributeError as e:
            return make_res(code=-1, message="请求方式错误")
        # website_url = req_data.get("front-url", current_app.config["WEBSITE_URL"])
        # website_url = request.remote_addr
        username = req_data.get('username')
        if username is None:
            return make_res(code=-1, message="请填写用户名")

        try:
            rest = RestPasswordForm(username=username)
            rest_token = rest.send_mail_code()
            return make_res(message="重置链接已经发送到您的邮箱", data={
                "token": rest_token
            })
        except ValueError as e:
            current_app.logger.info(e)
            return make_res(code=-1, message=str(e))
        except Exception as e:
            current_app.logger.warning(e)
            return make_res(code=-1, message=str(e))

# 重置密码接口
class ResetPasswordView(Resource):
    decorators = [auth.login_required]
    def post(self):
        try:
            req_data = request.get_json()
            print(req_data)
            new_password = req_data.get('new_password')
            user:User = User.query.get(g.user)
            user.set_password(new_password)
            db.session.add(user)
            db.session.commit()
            return make_res(message='reset password successful.')
        except ValueError as e:
            current_app.logger.info(e)
            return make_res(code=-1, message=str(e))
        except Exception as e :
            current_app.logger.error(e)
            return make_res(code=-9)

# 后端不负责注销，由前端实现，该部分为测试使用
class Logout(Resource):
    ''' 用户登出接口 '''
    decorators = [auth.login_required]

    def get(self):
        return "logout"

# 登录测试接口
class LoginTest(Resource):
    decorators = [auth.login_required]

    def get(self):
        user = User.query.get(g.user)
        username = user.username
        return {
            "message": "You was lgoin.",
            "data": username
        }


api.add_resource(Reg, "/regUser")
api.add_resource(Login, "/login")
# api.add_resource(Logout, "/logout")
api.add_resource(SendForgetCodeView, '/sendForgetCode')
api.add_resource(CheckResetCode, '/checkCode')
api.add_resource(LoginTest, "/loginTest")
api.add_resource(ResetPasswordView, '/resetPassword')
